# !/usr/bin/env python
# -*- coding: utf-8 -*-
import shelve
from app_config import BaseConfig

import sys
reload(sys)
sys.setdefaultencoding('utf8')

import requests
import json
import time
import hashlib
from WXBizMsgCrypt import WXBizMsgCrypt

open_token = BaseConfig.open_token
component_appid = BaseConfig.component_appid
component_appsecret = BaseConfig.component_appsecret
encodingAESKey = BaseConfig.encodingAESKey


class WxOpenCallback:
    def __init__(self):
        self.token = open_token

    def check_signature(self, pams):
        if not self.token:
            return 'TOKEN is not defined!'
        signature = pams.get('signature', '')
        timestamp = pams.get('timestamp', '')
        nonce = pams.get('nonce', '')
        tmparr = [self.token, timestamp, nonce]
        tmparr.sort()
        string = ''.join(tmparr)
        string = hashlib.sha1(string).hexdigest()
        # print signature
        # print string
        return signature == string


class WxOpenSDK:
    def __init__(self, ticket=''):
        self.component_appid = component_appid
        self.component_appsecret = component_appsecret
        self.ticket = ticket
        #self.db_file = 'wx_data_%s.db'%from_appid
        self.db_file = 'wx_data.db'
        if not self.ticket:
            db = shelve.open(self.db_file)  # 打开一个文件
            self.ticket = db['ComponentVerifyTicket']
            db.close()  # 关闭文件
            
    def get_com_access_token(self):
        # load file
        db = shelve.open(self.db_file)  # 打开一个文件
        component_access_token = db['component_access_token'] if 'component_access_token' in db else ''
        component_access_token_time = db['component_access_token_time'] if 'component_access_token_time' in db else ''
        db.close()  # 关闭文件
        
        now = time.time()
        print component_access_token_time,now
        if not component_access_token or component_access_token_time < now:
            url = "https://api.weixin.qq.com/cgi-bin/component/api_component_token"
            payload = {'component_appid': self.component_appid,
                   'component_appsecret': self.component_appsecret,
                   'component_verify_ticket': self.ticket}
            headers = {'content-type': 'application/json'}
            response = requests.post(url, data=json.dumps(payload), headers=headers)
            print '---get_com_access_token---', response.content
            response_json = response.json()
            print response_json
            if 'errcode' in response_json:
                print '---!!!!!error!!!!!!----',response_json
                print '---!!!!!payload!!!!!!----',payload
            component_access_token = response_json['component_access_token'] if 'component_access_token' in response_json else ''

            component_access_token_time = int(now) + 6500
            # save component_access_token
            if component_access_token:
                db = shelve.open(self.db_file)
                db['component_access_token'] = component_access_token
                db['component_access_token_time'] = component_access_token_time
                db.close()
        print 'component_access_token',component_access_token
        return component_access_token

    def get_pre_auth_code(self):
        now = time.time()
        # load file
        db = shelve.open(self.db_file)
        pre_auth_code = db['pre_auth_code'] if 'pre_auth_code' in db else ''
        pre_auth_code_time = db['pre_auth_code_time'] if 'pre_auth_code_time' in db else ''
        db.close()
        if not pre_auth_code or pre_auth_code_time < now:
            url = "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token=%s"\
                  % self.get_com_access_token()
            payload = {'component_appid': self.component_appid}
            headers = {'content-type': 'application/json'}
            response = requests.post(url, data=json.dumps(payload), headers=headers)
            print '---get_pre_auth_code---', response.content
            pre_auth_code = json.loads(response.text)['pre_auth_code']
            pre_auth_code_time = int(now) + 1100
            # save pre_auth_code
            db = shelve.open(self.db_file)
            db['pre_auth_code'] = pre_auth_code
            db['pre_auth_code_time'] = pre_auth_code_time
            db.close()
        return pre_auth_code

    def get_authorization_info(self, authorization_code):
        url = 'https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=%s' \
              % self.get_com_access_token()
        payload = {
            "component_appid": self.component_appid,
            "authorization_code": authorization_code
        }
        headers = {'content-type': 'application/json'}
        response = requests.post(url, data=json.dumps(payload), headers=headers)
        data = response.json()
        print 'authorization_info',data
        return data['authorization_info']

    def get_refresh_authorizer_access_token(self, authorizer_appid, authorizer_refresh_token):
        url = 'https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token=%s' \
              % self.get_com_access_token()
        payload = {
            "component_appid": self.component_appid,
            "authorizer_appid": authorizer_appid,
            "authorizer_refresh_token": authorizer_refresh_token
        }
        headers = {'content-type': 'application/json'}
        response = requests.post(url, data=json.dumps(payload), headers=headers)
        return response.json()

    def get_authorizer_info(self, authorizer_appid):
        url = 'https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token=%s' \
              % self.get_com_access_token()
        payload = {
            "component_appid": self.component_appid,
            "authorizer_appid": authorizer_appid
        }
        headers = {'content-type': 'application/json'}
        response = requests.post(url, data=json.dumps(payload), headers=headers)
        data = response.json()
        
        return data['authorizer_info']
        # return data


class WxUtils:
    def get_encrypt_xml(self, reply_xml, nonce):
        reply_xml=reply_xml.encode('utf-8')
        encrypt = WXBizMsgCrypt(open_token, encodingAESKey, component_appid)
        ret_encrypt, encrypt_xml = encrypt.EncryptMsg(reply_xml, nonce)
        if ret_encrypt == 0:
            return encrypt_xml
        else:
            return str(ret_encrypt)+' error'

    def get_decrypt_xml(self, encrypt_xml, msg_signature, timestamp, nonce):
        decrypt = WXBizMsgCrypt(open_token, encodingAESKey, component_appid)
        ret_decrypt, decrypt_xml = decrypt.DecryptMsg(encrypt_xml,
                                             msg_signature,
                                             timestamp,
                                             nonce)
        if ret_decrypt == 0:
            return decrypt_xml
        else:
            return str(ret_decrypt)+' error'
